﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using SignInServer.Server.Configuration;

namespace SignInServer.Server
{
    /// <summary>
    /// 服务器总类，负责监听端口
    /// </summary>
    class SocketServer
    {
        /// <summary>
        /// 服务器监听连接端口
        /// </summary>
        private Socket serverSocket;
        /// <summary>
        /// 链接池
        /// </summary>
        private ClientConn[] clientConn;
        //0:未开启；1：开启；2：报错
        public int serverStatus = 0;

        public SocketServer()
        {
            InitAllConn();
        }

        /// <summary>
        /// 开启服务器监听功能
        /// </summary>
        public void OpenServer()
        {
            IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Any, SocketConfiguration.PORT);
            Console.WriteLine("开启服务:"+ IPAddress.Any);
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(iPEndPoint);
            serverSocket.Listen(SocketConfiguration.CONN_SIZE);
            serverStatus = 1;
            serverSocket.BeginAccept(AcceptCb, null);
        }
        /// <summary>
        ///  初始化链接池
        /// </summary>
        private void InitAllConn()
        {
            clientConn = new ClientConn[SocketConfiguration.CONN_SIZE];

            for (int i = 0; i < SocketConfiguration.CONN_SIZE; i++)
            {
                clientConn[i] = new ClientConn(i);
            }
        }

        /// <summary>
        /// 监听客户端回调函数
        /// </summary>
        /// <param name="asyncResult">异步操作状态</param>
        private void AcceptCb(IAsyncResult asyncResult)
        {
            try
            {
                Socket socket = serverSocket.EndAccept(asyncResult);
                int index = FindNullConn();
                if (index == -1)
                {
                    //客户端连接已满 
                }
                else
                {
                    //开启该连接
                    clientConn[index].OpenConn(socket);
                    //重新监听新信号
                    serverSocket.BeginAccept(AcceptCb, null);
                    Console.WriteLine("重新监听");
                }
        }
            catch (Exception ex)
            {
                Console.WriteLine("异步监听失败:" + ex.Message);
                serverStatus = 2;
            }
}
        /// <summary>
        /// 寻找空闲的链接
        /// </summary>
        /// <returns></returns>
        private int FindNullConn()
        {
            if (clientConn == null)
            {
                return -1;
            }
            for (int i = 0; i < clientConn.Length; i++)
            {
                if (clientConn[i].connStatus == false)
                {
                    return i;
                }
            }
            return -1;
        }
    }
}
